package com.tanhua.server.service;

import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.constant.Constants;
import com.tanhua.dubbo.api.db.QuestionApi;
import com.tanhua.dubbo.api.db.UserApi;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.RecommendUserApi;
import com.tanhua.dubbo.api.mongo.UserLikeApi;
import com.tanhua.dubbo.api.mongo.UserLocationApi;
import com.tanhua.dubbo.api.mongo.VisitorApi;
import com.tanhua.model.db.Question;
import com.tanhua.model.db.User;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.UserLike;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.RecommendUserVo;
import com.tanhua.model.vo.TodayBestVo;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 交友模块业务处理层
 */
@Service
@Slf4j
public class TanhuaService {

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @DubboReference
    private UserApi userApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Value("${tanhua.default.recommend.users}")
    private String recommendUsers;

    @DubboReference
    private UserLikeApi userLikeApi;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @DubboReference
    private UserLocationApi userLocationApi;

    @DubboReference
    private VisitorApi visitorApi;

    /**
     * 今日佳人
     */
    public TodayBestVo todayBest() {
        Long userId = UserHolder.getUserId();//当前登录用户id
        //1 构造查询条件 调用服务查询今日佳人信息（只有一条记录） recommend_user  toUserId = userId(自己的用户id)
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        //2 如果今日佳人数据为空 直接设置 客服佳信息
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            //1-99都是客服
            long serviceUserId = userId % 99 + 1;
            recommendUser.setUserId(serviceUserId);
            recommendUser.setScore(88d);
        }
        //3 根据推荐用户id查询用户信息（tb_user_info）  recommendUser.getUserId()(被推荐的用户id)
        UserInfo userInfo = userInfoApi.getUserInfo(recommendUser.getUserId());
        //3.1 调用vo中的init方法 基于userInfo recommendUser对象 构造 TodayBestVo
        return TodayBestVo.init(userInfo, recommendUser);
    }

    /**
     * 推荐朋友
     */
    public PageResult<TodayBestVo> recommendation(RecommendUserVo recommendUserVo) {
        Long page = recommendUserVo.getPage(); //当前页码
        Long pagesize = recommendUserVo.getPagesize();//每页显示条数
        Long userId = UserHolder.getUserId();
        Integer age = recommendUserVo.getAge(); //年龄 age<xxx
        String gender = recommendUserVo.getGender();//性别 gender=xx
        //1 调用服务提供者 分页查询推荐用户列表数据
        PageResult<RecommendUser> rupr = recommendUserApi.findPage(userId, page, pagesize);
        //2 没有查询到推荐用户列表数据，则设置默认推荐好友数据
        if (rupr == null || CollectionUtils.isEmpty(rupr.getItems())) {
            rupr.setItems(getDefaultRecommendUserList());// 获取默认的客服
            rupr.setCounts(10l);
            rupr.setPage(1l);
            rupr.setPages(1l);
        }
        //3 获取推荐用户的ids 以及  gender age 查询userInfo
        List<RecommendUser> recommendUserList = rupr.getItems();
        List<Long> listUserIds = new ArrayList<>();
        //List<Long> collect = recommendUserList.stream().map(RecommendUser::getUserId).collect(Collectors.toList());
        for (RecommendUser recommendUser : recommendUserList) {
            listUserIds.add(recommendUser.getUserId());//10条记录
        }
        UserInfo userInfoCondtion = new UserInfo();
        userInfoCondtion.setAge(age);
        userInfoCondtion.setGender(gender);
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(listUserIds, userInfoCondtion);
        //4 循环遍历推荐用户列表 构造 TodayBestVo 返回
        List<TodayBestVo> todayBestVoList = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUserList) {
            Long recommendUserUserId = recommendUser.getUserId(); //推荐用户的id
            UserInfo userInfo = userInfoMap.get(recommendUserUserId);
            if (null != userInfo) {
                todayBestVoList.add(TodayBestVo.init(userInfo, recommendUser));
            }
        }
        return new PageResult<>(rupr.getCounts(), rupr.getPagesize(), rupr.getPages(), rupr.getPage(), todayBestVoList);
    }


    /**
     * 默认客服
     *
     * @return
     */
    private List<RecommendUser> getDefaultRecommendUserList() {
        List<RecommendUser> list = new ArrayList<>();
        // 随机产生开始的客户id, 从这个客服的id开始，往后取10个
        int startIndex = RandomUtils.nextInt(1, 90);
        RecommendUser recommendUser = null;
        for (long i = startIndex; i < startIndex + 10; i++) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(i);
            recommendUser.setScore(RandomUtils.nextDouble(70, 88));
            list.add(recommendUser);
        }
        return list;
    }

    /**
     * 佳人信息
     */
    public TodayBestVo personalInfo(Long personId) {
        //1 根据佳人用户id调用服务获取佳人详情
        UserInfo userInfo = userInfoApi.getUserInfo(personId);
        //2 根据佳人用户id 当前用户id 查询RecommendUser 获取缘分值
        RecommendUser recommendUser = recommendUserApi.findByUserId(UserHolder.getUserId(), personId);
        //2.1查询recommendUser为空 设置 默认数据
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setScore(88d);
        }
        //3.调用服务保存访客记录
        Visitors visitors = new Visitors();
        visitors.setUserId(personId);//佳人的用户id
        visitors.setVisitorUserId(UserHolder.getUserId());//来访的用户id(登录用户id)
        visitors.setFrom("首页");//访客来源 首页 视频 个人信息等
        visitors.setScore(recommendUser.getScore());//缘分值
        visitorApi.save(visitors);
        //3 基于userInfo RecommendUser构造Vo
        return TodayBestVo.init(userInfo, recommendUser);
    }

    /**
     * 查询陌生人问题
     */
    public String strangerQuestions(Long userId) {
        //1根据陌生人用户id调用服务查询问题表
        Question question = questionApi.findByUserId(userId);
        //2如果问题内容不存在 则设置默认问题
        String strangerQuestion = "妹子带孩子去了";//默认值
        //1.1 如果question为空默认问题
        if (question != null && !StringUtils.isEmpty(question.getTxt())) {
            strangerQuestion = question.getTxt();//数据库内容
        }
        //3返回陌生人问题
        return strangerQuestion;
    }

    /**
     * 回复陌生人问题
     */
    public void replyStrangerQuestions(Map params) {
        Long personUserId = Long.valueOf(params.get("userId").toString());//佳人用户id
        String content = (String) params.get("reply");//当前用户回复的内容
        Long userId = UserHolder.getUserId();//当前登录用户id
        //1根据佳人用户id 查询佳人信息tb_user（得到环信hx_user）
        User personUser = userApi.findById(personUserId);
        //2根据当前登录用户id查询用户详情tb_user_info （得到昵称）
        UserInfo userInfo = userInfoApi.getUserInfo(userId);
        //3根据当前登录用户id查询用户对象tb_user （得到hx_user）
        User currentUser = userApi.findById(userId);
        //4构造环信消息内容 调用环信发送消息
        Map<String, Object> message = new HashMap<>();
        //{"userId":1,"huanXinId":"hx1","nickname":"1号技师","strangerQuestion":"10012问题你服务好吗？","reply":"很好包你满意"}
        message.put("userId", userId);//当前登录用户id
        message.put("huanXinId", currentUser.getHxUser());//当前登录用户的环信ID
        message.put("nickname", userInfo.getNickname());//当前登录用户昵称
        message.put("strangerQuestion", strangerQuestions(personUserId));//佳人问题
        message.put("reply", content);
        log.debug("******************发送消息给{}，内容{}********************", personUser.getHxUser(), JSON.toJSONString(message));
        if (!huanXinTemplate.sendMsg(personUser.getHxUser(), JSON.toJSONString(message))) {
            log.debug("******************************环信发送消息失败了********************************");
        }
    }

    /**
     * 探花推荐列表查询
     */
    public List<TodayBestVo> cards() {
        Long userId = UserHolder.getUserId();//当用户id
        //1.调用服务随机获取 10个推荐用户数据
        List<RecommendUser> recommendUserList = recommendUserApi.findCards(userId, 10);
        //2. 如果没有获取到推荐用户数据 则设置默认数据
        if (CollectionUtils.isEmpty(recommendUserList)) {
            String[] recommendUserIds = recommendUsers.split(",");//数组
            recommendUserList = new ArrayList<>();
            for (String recommendUserId : recommendUserIds) {
                RecommendUser ru = new RecommendUser();
                ru.setUserId(Long.valueOf(recommendUserId));//推荐的用户id
                ru.setToUserId(userId);//当前用户id
                ru.setScore(88d);
                recommendUserList.add(ru);
            }
        }
        //3. 获取出所有的推荐用户ids userIds
        List<Long> listUserIds = recommendUserList.stream().map(RecommendUser::getUserId).collect(Collectors.toList());
        //4. 根据userIds批量查询用户详情 tb_user_info
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(listUserIds, null);
        //5. 循环遍历推荐用户数据 基于推荐用户数据 以及 用户详情 构造TodayBestVO返回
        List<TodayBestVo> todayBestVoList = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUserList) {
            UserInfo userInfo = userInfoMap.get(recommendUser.getUserId());
            if (null != userInfo) {
                todayBestVoList.add(TodayBestVo.init(userInfo, recommendUser));
            }
        }
        return todayBestVoList;
    }

    /**
     * 探花-喜欢(右滑)
     * 探花-不喜欢（左滑）
     */
    public void love(Long likeUserId, boolean isLike) {
        Long userId = UserHolder.getUserId();
        //1.调用服务保存 喜欢 或 不喜欢 记录
        UserLike userLike = new UserLike();
        userLike.setUserId(userId);//当前登录用户id
        userLike.setLikeUserId(likeUserId);//喜欢或不喜欢的用户id
        userLike.setIsLike(isLike);//是否喜欢 true:喜欢 false:不喜欢
        boolean isFriend = userLikeApi.save(userLike);
        //2.根据喜欢或不喜欢操作Redis记录 （后续例如：首页点击某个推荐用户 需要查询此redis数据）
        String likeKey = Constants.USER_LIKE_KEY + UserHolder.getUserId();//USER_LIKE_SET_10012  1,2,3
        String unlikeKey = Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId();//USER_NOT_LIKE_SET_10012 4,5,6
        if (isLike) {//喜欢 redis set集合
            stringRedisTemplate.opsForSet().add(likeKey, likeUserId.toString());
            stringRedisTemplate.opsForSet().remove(unlikeKey, likeUserId.toString());
        } else {
            stringRedisTemplate.opsForSet().remove(likeKey, likeUserId.toString());
            stringRedisTemplate.opsForSet().add(unlikeKey, likeUserId.toString());
        }
        //3.如果是互相喜欢调用环信云保存好友关系
        if(isFriend){
            //注意：环信后台一定要先添加测试的用户
            huanXinTemplate.addContact(Constants.HX_USER_PREFIX+userId,Constants.HX_USER_PREFIX+likeUserId);
        }
    }

    /**
     * 搜附近
     */
    public List<NearUserVo> searchNearBy(String gender, Long distance) {
        Long userId = UserHolder.getUserId();
        //1.调用服务获取附近用户ids(条件：当前登录用户id 搜索距离 半径)
        List<Long> nearUserIds = userLocationApi.searchNearBy(userId,distance);
        //2.根据附近用户ids 以及 需要搜索的性别 调用服务查询附近用户的详情
        if(!CollectionUtils.isEmpty(nearUserIds)){
            UserInfo uc = new UserInfo();
            uc.setGender(gender);
            Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(nearUserIds, uc);
            //3.基于用户的详情 构造VO返回
            List<NearUserVo> nearUserVoList = userInfoMap.values().stream().map(u -> NearUserVo.init(u)).collect(Collectors.toList());
            return nearUserVoList;

        }
        return null;
    }
}
